import AceEditor from 'react-ace';
import 'ace-builds/src-min-noconflict/ext-searchbox';
import 'ace-builds/src-min-noconflict/ext-language_tools';
import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-github";
import ProForm, { ProFormSelect } from '@ant-design/pro-form' ;
import ProCard from '@ant-design/pro-card';
import { PlusOutlined } from '@ant-design/icons';
import { Button, message, Tabs, Space} from 'antd';
import React, {useState, useRef, useEffect} from 'react';
import { PageContainer } from '@ant-design/pro-layout';
import ProTable, { ProColumns, ActionType } from '@ant-design/pro-table';
import CreateForm from './components/CreateForm';
import UpdateForm from './components/UpdateForm';
import DeleteForm from './components/DeleteForm';
import {
  KConfigItem,
  KConfigDeleteItem,
  KConfigAddItem,
  KConfigUpdateItem,
  KConfigGetConfigPreviewParam, InstanceList,
  KInstance,
  TemplateList,
  TemplateSelect,
  KGetTemplatePreviewParam,
} from './data.d';
import {
  queryItemConfig, queryTemplateConfig, updateTemplateConfig,
  addItemConfig, updateItemConfig, removeItemConfig, getConfigPreview, queryInstances,
  queryTempldateList,
  queryTemplateByID,
  queryLock,
  deleteLock,
} from './service';

/**
 * 添加节点
 * @param fields
 */
const handleAddItem = async (fields: KConfigAddItem) => {
  if (fields.confValue === undefined) {
    // eslint-disable-next-line no-param-reassign
    fields.confValue = '';
  }
  const hide = message.loading('正在添加');
  try {
    await addItemConfig({ ...fields });
    hide();
    message.success('添加成功');
    return true;
  } catch (error) {
    hide();
    message.error('添加失败请重试！');
    return false;
  }
};

/**
 * 更新节点
 * @param fields
 */
const handleUpdateItem = async (fields: KConfigUpdateItem) => {
  const hide = message.loading('正在配置');
  try {
    await updateItemConfig({
      ...fields
    });
    hide();
    message.success('配置成功');
    return true;
  } catch (error) {
    hide();
    message.error('配置失败请重试！');
    return false;
  }
};

/**
 *  删除节点
 * @param fields
 */
const handleDeleteItem = async (fields: KConfigDeleteItem) => {
  const hide = message.loading('正在删除');
  try {
    await removeItemConfig({ ...fields
    });
    hide();
    message.success('删除成功，即将刷新');
    return true;
  } catch (error) {
    hide();
    message.error('删除失败，请重试');
    return false;
  }
};

/**
 * 获取环境列表
 */
const handleQueryInstance = async () => {
  const instanceList: InstanceList[] = new Array<InstanceList>();
  try {
    await queryInstances().then(
      (result) => {
        result.data.forEach((eachLine: KInstance) => {
          instanceList.push({label: eachLine.name, value: eachLine.name});
        });
      },
    );
    return instanceList;
  } catch {
    return instanceList;
  }
};
/**
 * 获取模板历史记录
 */
const handleQueryTemplateHistory = async () => {
  const templateSelect: TemplateSelect[] = new Array<TemplateSelect>();
  try {
    await queryTempldateList().then(
      (result) => {
        result.data.forEach((eachLine: TemplateList) => {
          templateSelect.push({label: `${eachLine.name  } ${  eachLine.createdAt  } ${  eachLine.user}`, value: eachLine.id})
        });
      },
    );
    return templateSelect;
  } catch {
    return templateSelect;
  }
};


/**
 * 获取配置文件预览
 */


const { TabPane } = Tabs;

const TableList: React.FC = () => {
  const [createModalVisible, setCreateModalVisible] = useState<boolean>(false);
  const [updateModalVisible, setUpdateModalVisible] = useState<boolean>(false);
  const [deleteModalVisible, setDeleteModalVisible] = useState<boolean>(false);
  const [formValues, setFormValues] = useState({});
  const [previewTitle, setPreviewTitle] = useState("");
  const [previewContent, setPreviewContent] = useState("");
  const [templatePreview, setTemplatePreview] = useState<TemplateList>();
  const [deleteValues, setDeleteValues] = useState({});
  const actionRef = useRef<ActionType>();
  const [editorReadOnly, setEditorReadOnly] = useState<boolean>(true);
  /*
  const [row, setRow] = useState<KConfigItem>();
  */
  const [templateValues, updateTemplateValues] = useState("");

  const handleUpdateTemplate = async (fields: {content:string}) => {
    const hide = message.loading('正在配置');
    try {
      await updateTemplateConfig({...fields});
      hide();
      message.success('更新配置模板成功');
      setEditorReadOnly(true)
      return true;
    } catch (error) {
      hide();
      message.error('更新配置模板失败请重试！');
      return false;
    }
  };

  const handleGetConfigPreview = async (fields: KConfigGetConfigPreviewParam) => {
    const hide = message.loading('正在获取配置文件');
    const {status, content} = await getConfigPreview({...fields})
    if (status === 'ok') {
      setPreviewTitle(fields.instanceName);
      setPreviewContent(content);
      hide();
      message.success('获取成功');
      return true;
    }
    if (status === 'error') {
      setPreviewTitle(`${fields.instanceName  }  Error Message`);
      setPreviewContent(content);
      hide();
      message.error('请查看错误信息');
      return true;
    }
    setPreviewTitle('');
    setPreviewContent('');
    hide();
    message.error('获取配置文件失败!');
    return false;
  };

  const handleGetTemplatePreview = async (fields: KGetTemplatePreviewParam) => {
    const hide = message.loading('正在历史模板文件');
    const {status, data} = await queryTemplateByID({...fields})
    if (status === 'ok') {
      setTemplatePreview(data);
      hide();
      message.success('获取成功');
      return true;
    }
    setTemplatePreview({id: 0, name: '', content: '', user: '', createdAt: new Date()});
    hide();
    message.error('获取历史模板失败!');
    return false;
  };

  const releaseLockaResetTemplate = async() => {
    await deleteLock();
    setEditorReadOnly(true);
  }
  let timeOut1: ReturnType<typeof setTimeout>
  const handleStartEdit = async() => {
    if (editorReadOnly) {
      /* first to get a lock, then reload template config content
       */
      const hide = message.loading('正在请求锁');
      const {status, data} = await queryLock();
      console.log(data);
      if (status === 10200) {
        hide();
        const hide2 = message.loading('正在请求配置数据');
        const {status: status2, data: data2} =  await queryTemplateConfig();
        if (status2 === 10200 ) {
          hide2();
          updateTemplateValues(data2.data);
          setEditorReadOnly(false);
        } else {
          hide2();
          updateTemplateValues('');
          message.error('获取配置模板失败');
          /* release lock */
          await deleteLock();
        }
        /* add timeout function to release lock */
        timeOut1 = setTimeout(releaseLockaResetTemplate, 360000);
      } else {
        hide();
        message.error(`获取编辑锁失败:${  data}`);
      }
    } else {
      if (timeOut1) {
        clearTimeout(timeOut1);
      }
      /* first unlock the lock, then reload template config content */
      const hide = message.loading('释放编辑锁');
      const {status, data} = await deleteLock();
      if (status === 10200 ) {
        hide();
        message.success('释放锁成功')
        setEditorReadOnly(true);
      } else {
        hide();
        message.error(`锁释放出错:${ data}`);
        setEditorReadOnly(true);
      }
    }
  };

  useEffect(() => {
    queryTemplateConfig()
      .then((data) => {
        console.log(data);
        updateTemplateValues(data.data);
      })
      .catch(() => {
        updateTemplateValues("");
      });
  }, []);

  const addColumns: ProColumns<KConfigAddItem>[] = [
    {title: 'confName', dataIndex: 'confName'},
    {title: 'confValue', dataIndex: 'confValue'},
  ];

  const columns: ProColumns<KConfigItem>[] = [
    {
      title: '变量名',
      dataIndex: 'confName',
      sorter: (a, b) => 0 - (a.confName > b.confName ? 1: -1),
      formItemProps: {
        rules: [
          {
            required: true,
            message: '变量名为必填项',
          },
        ],
      },
    },
    {
      title: '变量类型',
      dataIndex: 'confType',
      valueEnum: {
        1: {text: '替换型', status: 'Default'},
        2: {text: '普通型', status: 'Success'},
      },
      hideInForm: true,
    },
    {
      title: '创建时间',
      dataIndex: 'createdAt',
      sorter: (a, b) => 0 - (a.createdAt > b.createdAt ? 1 : -1),
      valueType: 'dateTime',
      hideInForm: true,
    },
    {
      title: '创建者',
      dataIndex: 'user',
      hideInForm: true,
    },
    {
      title: '操作',
      dataIndex: 'option',
      valueType: 'option',
      render: (_, record) => (
        <>
          <a onClick={() => {
            setDeleteModalVisible(true);
            setDeleteValues(record);}}
          >删除</a>
        </>
      ),
    },
  ];


  const expandedRowRender = (record: KConfigItem) => {
    const data = [];
    if (record && record.instances.length) {
      for (let i = 0; i < record.instances.length; i += 1) {
        data.push({ ...record.instances[i] });
      }
    }

    return (
      <ProTable
        columns={[
          {
            title: '值',
            dataIndex: 'confValue',
            width: '50%',
            copyable: true,
            ellipsis: true,
            formItemProps: {
              rules: [
                {
                  required: true,
                  message: '值为必填项',
                },
              ],
            },
          },
          {
            title: '环境名',
            dataIndex: 'instance',
          },
          {
            title: '最后修改时间',
            dataIndex: 'updatedAt',
            sorter: true,
            valueType: 'dateTime',
            hideInForm: true,
          },
          {
            title: '修改者',
            dataIndex: 'user',
            sorter: true,
            hideInForm: true,
          },
          {
            title: '操作',
            dataIndex: 'option',
            valueType: 'option',
            key: 'operation',
            render: (_, innerRecord) => (
              <>
                <a
                  onClick={() => {
                    setUpdateModalVisible(true);
                    setFormValues(innerRecord);
                  }}
                >
                  修改
                </a>
              </>
            ),
          },
        ]}
        rowKey="key"
        headerTitle={false}
        search={false}
        options={false}
        dataSource={data}
        pagination={false}
      />
    );
  };

  return (
    <PageContainer>
      <Tabs type="card">
        <TabPane tab="配置项" key="1">
          <ProTable<KConfigItem>
            actionRef={actionRef}
            rowKey="key"
            search={{
              labelWidth: 120,
            }}
            toolBarRender={() => [
              <Button key="1" type="primary" onClick={() => setCreateModalVisible(true)}>
                <PlusOutlined /> 新建
              </Button>,
            ]}
            request={(params) => queryItemConfig({ ...params })}
            columns={columns}
            expandable={{expandedRowRender}}
            options={false}
            pagination={false}
          />
        </TabPane>
        <TabPane tab="配置文件预览" key="2">
          <ProForm
            submitter={{
              searchConfig:{submitText: '预览'}
            }}
            layout="inline"
            onFinish={async (value) => {
              await handleGetConfigPreview(value);}
            }
          >
            <ProFormSelect
            name="instanceName"
            label="环境"
            hasFeedback
            request={handleQueryInstance}
            placeholder="选择一个环境"
            />
          </ProForm>
          <ProCard title={previewTitle} style={{ marginTop: 15}} headerBordered>
            <pre>
            {previewContent}
            </pre>
          </ProCard>
        </TabPane>
        <TabPane tab="配置模板" key="3">
          <Space direction="vertical">
          <Space>
            <Button type={editorReadOnly? 'primary' : 'default'} onClick={() => handleStartEdit()}>
              {editorReadOnly? '开始修改': '放弃修改'}
            </Button>
            <Button type="primary" disabled={editorReadOnly} onClick={() =>handleUpdateTemplate({content: templateValues})}>
              提交更新
            </Button>
          </Space>
          <AceEditor
            style={{width: 900}}
            value={templateValues}
            mode="python"
            theme="github"
            onChange={(code) => updateTemplateValues(code)}
            name="template_editor_div"
            // default is true
            highlightActiveLine
            showGutter
            fontSize={16}
            readOnly={editorReadOnly}
            setOptions={{
              enableBasicAutocompletion: false,
              enableLiveAutocompletion: false,
              enableSnippets: false,
              showLineNumbers: true,
              tabSize: 4,
              maxLines: 40,
            }}
          />
          </Space>
        </TabPane>
        <TabPane tab="模板历史记录" key="4">
          <ProForm
            submitter={{
              searchConfig:{submitText: '显示模板内容'}
            }}
            layout="inline"
            onFinish={async (values) => {
              await handleGetTemplatePreview(values);}
            }
          >
            <ProFormSelect
              name="id"
              label="模板记录"
              hasFeedback
              width="lg"
              request={handleQueryTemplateHistory}
              placeholder="选择一个"
            />
          </ProForm>
          <ProCard title={templatePreview? `${templatePreview.name  } ${  templatePreview.createdAt  } ${  templatePreview.user}` : ''} style={{ marginTop: 15}} headerBordered>
            <pre>
            {templatePreview? templatePreview.content : ''}
            </pre>
          </ProCard>
        </TabPane>
      </Tabs>

      <CreateForm onCancel={() => setCreateModalVisible(false)} modalVisible={createModalVisible}>
        <ProTable<KConfigAddItem, KConfigAddItem>
          onSubmit={async (value) => {
            const success = await handleAddItem(value);
            if (success) {
              setCreateModalVisible(false);
              if (actionRef.current) {
                actionRef.current.reload();
              }
            }
          }}
          rowKey="key"
          type="form"
          columns={addColumns}
        />
      </CreateForm>

      {formValues && Object.keys(formValues).length ? (
        <UpdateForm
          onSubmit={async (value) => {
            const success = await handleUpdateItem(value);
            if (success) {
              setUpdateModalVisible(false);
              setFormValues({});
              if (actionRef.current) {
                actionRef.current.reload();
              }
            }
          }}
          onCancel={() => {
            setUpdateModalVisible(false);
            setFormValues({});
          }}
          updateModalVisible={updateModalVisible}
          values={formValues}
        />
      ) : null}

      {deleteValues && Object.keys(deleteValues).length ? (
        <DeleteForm
          onSubmit={async (value) => {
            const success = await handleDeleteItem(value);
            if (success) {
              setDeleteModalVisible(false);
              setDeleteValues({});
              if (actionRef.current) {
                actionRef.current.reload();
              }
            }
          }}
          onCancel={() => {
            setDeleteModalVisible(false);
            setDeleteValues({});
          }}
          deleteModalVisible={deleteModalVisible}
          values={deleteValues}
        />
      ) : null}

    </PageContainer>
  );
};

export default TableList;
